package com.teamone.mobilewatch.model;

import java.util.ArrayList;

import com.teamone.mobilewatch.PatientWatchActivity;
import com.teamone.mobilewatch.R;
import com.teamone.mobilewatch.accessor.webservice.PatientWatchDataAccessorImpl;
import com.teamone.mobilewatch.util.UserSettings;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;

/**
 * Periodically updates watchlist with the latest patient readings retrieved from the backend  
 *
 */
public class WatchlistUpdater {
	private static final String TAG = "WatchlistUpdater";
	private int updatePeriod; //period between updates sec
	private Watchlist watchlist;
	private boolean started;
	private Handler handler;
	private UpdateThread updateThread;
	Context context;
	PatientWatchActivity patientWatchActivity;
	
	private static final int WATCHLIST_UPDATER_ID = 1;
	NotificationManager mNotificationManager;
	
	
	/**
	 * Constructs instance of WatchlistUpdater 
	 * @param watchlist - watchlist to be monitored and updated when monitor is running
	 */
	public WatchlistUpdater(Watchlist watchlist, PatientWatchActivity pwa){
		this.watchlist = watchlist;
		updatePeriod = UserSettings.getRefreshRate();
		started = false;
		context = pwa.getBaseContext();
		this.patientWatchActivity = pwa;
		mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
	}

	/**
	 * Starts WatchlistUpdater
	 */
	public void start() {
		if (!started) {
			started = true;
			if(updateThread == null) {
				updateThread = new UpdateThread();
				updateThread.start();
			}
		}
	}
	
	/**
	 * Stops WatchlistUpdater
	 */
	public void stop() {
		started = false;
		updateThread = null;
		// cancel notifications
		mNotificationManager.cancel(WATCHLIST_UPDATER_ID);
	}
	
	
	private void notifySyncStarted(){
		int icon = R.drawable.refresh_icon;
		CharSequence tickerText = "Updating watchlist...";
		long when = System.currentTimeMillis();
		Notification notification = new Notification(icon, tickerText, when);

		CharSequence contentTitle = "PatientWatch notification";
		CharSequence contentText = "Updating watchlist...";
		Intent notificationIntent = new Intent(context, PatientWatchActivity.class);
		PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
				notificationIntent, 0);
		notification.setLatestEventInfo(context, contentTitle, contentText,
				contentIntent);
		
		mNotificationManager.notify(WATCHLIST_UPDATER_ID, notification);			

	}
	
	private void notifySyncCompleted(){
		int icon = R.drawable.sync_icon;
		CharSequence tickerText = "Update completed.";
		long when = System.currentTimeMillis();
		Notification notification = new Notification(icon, tickerText, when);

		CharSequence contentTitle = "PatientWatch notification";
		CharSequence contentText = "Updating watchlist...";
		Intent notificationIntent = new Intent(context, PatientWatchActivity.class);
		PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
				notificationIntent, 0);
		notification.setLatestEventInfo(context, contentTitle, contentText,
				contentIntent);
		
		mNotificationManager.notify(WATCHLIST_UPDATER_ID, notification);			

	}
	
	private void notifySyncError(String errorMsg){
		int icon = R.drawable.unstable_icon;
		//CharSequence tickerText = "" + errorMsg;
		CharSequence tickerText = "Server is unavailable."; // hide the error message from the user
		long when = System.currentTimeMillis();
		Notification notification = new Notification(icon, tickerText, when);

		CharSequence contentTitle = "PatientWatch notification";
		CharSequence contentText = "Updating watchlist...";
		Intent notificationIntent = new Intent(context, PatientWatchActivity.class);
		PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
				notificationIntent, 0);
		notification.setLatestEventInfo(context, contentTitle, contentText,
				contentIntent);
		
		mNotificationManager.notify(WATCHLIST_UPDATER_ID, notification);			

	}
	
	
	
	private class UpdateThread extends Thread{
		private static final String TAG = "WatchlistUpdater:UpdateThread";
		private ArrayList<Patient> patients;
		private Handler handler = new Handler();
		
		public void run() {
			while(started) {
				try {
					
					notifySyncStarted();
					Log.d(TAG, "sync task started...");

					// sync task
					try {
						Log.d(TAG, "loading patients data...");

						// get data for patients in the watchlist
						patients = watchlist.getPatients();
						for (Patient patient : patients) {
							PatientReadings lastReadings = PatientWatchDataAccessorImpl
									.getInstance().getLastPatientReadings(
											patient.getPatientId());
							patient.setLastReadings(lastReadings);
						}
						Log.d(TAG, "patients.size=" + patients.size());
						// update UI
						handler.post(new Runnable() {
							@Override
							public void run() {
								patientWatchActivity.updateAdapter(patients);
								if (UserSettings.isVoiceAlerts()) {
									patientWatchActivity.voiceAlertCriticalCondition(patients);
								}
							}
						});
						notifySyncCompleted();						
						Log.d(TAG, "sync task completed... waiting for "+ updatePeriod + "sec");
					} catch (Exception e) {
						Log.e(TAG, e.toString());
						notifySyncError(e.toString());
					}
					Thread.sleep(updatePeriod * 1000);
				} catch (InterruptedException e) {
					Log.e(TAG, e.getMessage());
				}
			}
		}
		
	}
	

}
